﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Haidou.Wpf.Util
{
	/// <summary>
	/// 进程任务
	/// </summary>
	public static class ProcessHelper
	{
		/// <summary>
		/// 获取入口程序集路径
		/// </summary>
		/// <returns></returns>
		public static string GetEntryAssemblyPath()
		{
			try
			{
				return Process.GetCurrentProcess().MainModule?.FileName ??
					System.Reflection.Assembly.GetEntryAssembly()?.GetName().CodeBase?.Replace("/Haidou.Wpf.UI.dll", "/Haidou.Wpf.UI.exe") ??
					Path.Combine(AppContext.BaseDirectory, "Haidou.Wpf.UI.exe");
			}
			catch (Exception e)
			{
				LogWriter.Log(e, "Not possible to get current executing assembly path.||无法获取当前正在执行的程序集路径。");
				return Path.Combine(AppContext.BaseDirectory, "Haidou.Wpf.UI.exe");
			}
		}

		/// <summary>
		/// 获取条目NAudioenPath
		/// </summary>
		/// <returns></returns>
		public static string GetEntryNAudioenPath()
		{
			//DTo  详细试验目的
			try
			{
				return Path.Combine(AppContext.BaseDirectory, "NAudioen/NAudioen.pcm");
			}
			catch (Exception e)
			{
				LogWriter.Log(e, "Not possible to get current executing assembly path.||无法获取当前正在执行的程序集路径。");
				return Path.Combine(AppContext.BaseDirectory, "NAudioen/NAudioen.pcm");
			}
		}


		public static async Task<string> Start(string arguments, bool runWithPowershell = true)
		{
			ProcessStartInfo info = new(runWithPowershell ? "Powershell.exe" : "cmd.exe")
			{
				Arguments = (!runWithPowershell ? "/c " : "") + arguments,
				RedirectStandardOutput = true,
				CreateNoWindow = true
			};

			try
			{
				using Process process = new();
				process.StartInfo = info;
				process.Start();

				string message = await process.StandardOutput.ReadToEndAsync();

				await process.WaitForExitAsync();

				return message;
			}
			catch (Exception e)
			{
				LogWriter.Log(e, "It was not possible to run the command||无法运行该命令");
				return "";
			}
		}

		public static void StartWithShell(string filename)
		{
			try
			{
				ProcessStartInfo info = new()
				{
					Verb = "runas",
					FileName = filename,
					UseShellExecute = true
				};

				Process.Start(info);
			}
			catch (Exception ex)
			{

				LogWriter.Log(ex, "It was not possible to run the command||无法运行该命令");

			}



		}

		/// <summary>
		/// 以管理员身份重新启动
		/// </summary>
		/// <param name="arguments"></param>
		/// <param name="waitToClose"></param>
		/// <returns></returns>
		public static async Task<bool> RestartAsAdmin(string arguments = "", bool waitToClose = false)
		{
			try
			{
				ProcessStartInfo info = new()//GetEntryAssemblyPath()
				{
					UseShellExecute = true,
					Verb = "runas",
					Arguments = arguments
				};

				Process? process = Process.Start(info);

				if (waitToClose && process != null)
				{
					TaskCompletionSource<bool> comp = new();

					process.Exited += (sender, args) =>
					{
						comp.SetResult(process.ExitCode != 90);
					};
					process.EnableRaisingEvents = true;

					if (process.HasExited)
					{
						return process.ExitCode != 90;
					}

					//仅当区域被选中时返回。
					return await comp.Task;
				}

				return true;
			}
			catch (Win32Exception ex)
			{
				if (ex.NativeErrorCode != 1223) //用户已取消。
				{
					LogWriter.Log(ex, "Impossible to start process as admin.||无法以管理员身份启动进程。");
				}

				return false;
			}
			catch (Exception e)
			{
				LogWriter.Log(e, "Impossible to start process as admin.||无法以管理员身份启动进程。");
				return false;
			}
		}
		/// <summary>
		/// 重新启动终端高级
		/// </summary>
		/// <param name="arguments"></param>
		/// <returns></returns>
		public static Process RestartAsAdminAdvanced(string arguments = "")
		{
			try
			{
				ProcessStartInfo info = new(GetEntryAssemblyPath())
				{
					UseShellExecute = true,
					Verb = "runas",
					Arguments = arguments
				};

				return Process.Start(info);
			}
			catch (Win32Exception ex)
			{
				if (ex.NativeErrorCode != 1223) //User cancelled.用户已取消。
				{
					LogWriter.Log(ex, "Impossible to start process as admin.无法以管理员身份启动流程");
				}

				return null;
			}
			catch (Exception e)
			{
				LogWriter.Log(e, "Impossible to start process as admin.无法以管理员身份启动流程");
				return null;
			}
		}
	}
}
